package com.woniu.mealsService.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.dto.CommentDto;
import com.woniu.exception.meals.FeignException;
import com.woniu.exception.meals.MealsException;
import com.woniu.mealsService.model.Comment;
import com.woniu.mealsService.mapper.CommentMapper;
import com.woniu.mealsService.model.CommentFileUpload;
import com.woniu.mealsService.model.OrderProduct;
import com.woniu.mealsService.model.Store;
import com.woniu.mealsService.service.CommentFileUploadService;
import com.woniu.mealsService.service.CommentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.mealsService.service.OrderProductService;
import com.woniu.mealsService.service.StoreService;
import com.woniu.param.AddCommentParam;
import com.woniu.param.replyCommentParam;
import com.woniu.server.RedisKey;
import com.woniu.server.RedisUtil;
import com.woniu.user.client.UserFeignClient;
import com.woniu.user.dto.UserInfoFeignDto;
import com.woniu.utils.EnumException;
import com.woniu.utils.PageInfo;
import com.woniu.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 评价表 服务实现类
 * </p>
 *
 * @author jiang
 * @since 2024年12月09日
 */
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {
    @Autowired
    private UserFeignClient userFeignClient;
    @Autowired
    private CommentFileUploadService commentFileUploadService;
    @Autowired
    private StoreService storeService;
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private OrderProductService orderProductService;
    @Override
    @Transactional
    // 添加评论
    public String addComment(AddCommentParam bean,String userId) throws Exception {
        Comment one = this.getOne(new LambdaQueryWrapper<Comment>().eq(Comment::getOrderId, bean.getOrderId()).eq(Comment::getUserId, userId).eq(Comment::getStoreId, bean.getStoreId()));
        if (null != one){
            throw new RuntimeException("请勿重复评论");
        }
        OrderProduct orderProduct = orderProductService.getOne(new LambdaQueryWrapper<OrderProduct>().eq(OrderProduct::getOrderId, bean.getOrderId()));
        if (null == orderProduct){
            throw new RuntimeException("订单不存在");
        }
        if (orderProduct.getOrderState()!=4 && orderProduct.getOrderState()!=8){
            throw new RuntimeException("订单状态异常");
        }
        Comment comment = new Comment();
        BeanUtil.copyProperties(bean, comment);
        comment.setUserId(userId);
        comment.setUserName(bean.getUserName());
        comment.setUserImg(bean.getUserImg());
        comment.setContent(bean.getComment());
        // 传入的图片路径集合与redis存入的集合的交集
        List<String> collect = null;
        // 传入的图片路径集合与redis存入的集合的差集
        List<String> pics = null;
        if (bean.getPictureFlag()==1){
            String picList = redisUtil.get(RedisKey.saveUploadCommentPic(Long.parseLong(userId)));
            pics= JSONUtil.toList(picList, String.class);
            collect =  pics.stream().filter(bean.getPictureUrls()::contains).collect(Collectors.toList());
            pics.removeAll(bean.getPictureUrls());
            redisUtil.del(RedisKey.saveUploadCommentPic(Long.parseLong(userId)));
        }
        // 新增评论
        commentMapper.insert(comment);
        commentFileUploadService.insertFilePath(collect,bean.getOrderId());
        commentFileUploadService.removeFile(pics);
        return "添加评论成功";
    }

    @Override
    @Transactional
    // 删除评论
    public boolean deleteComment(String orderId, String userId) throws Exception {
//        Comment comment = this.getOne(new LambdaQueryWrapper<Comment>().eq(Comment::getOrderId, orderId).eq(Comment::getUserId, userId));
        Comment comment = commentMapper.select(null,null,orderId, userId);
        if (null == comment){
            throw new MealsException(EnumException.COMMENT_NULL_EXCEPTION);
        }
        if (comment.getPictureFlag()==1){
//            List<CommentFileUpload> list = commentFileUploadService.list(new LambdaQueryWrapper<CommentFileUpload>().eq(CommentFileUpload::getOrderId, orderId));
            List<CommentFileUpload> list = commentFileUploadService.getList(orderId);
            List<Integer> collect = list.stream().map(CommentFileUpload::getId).collect(Collectors.toList());
            commentMapper.removeOne(comment.getCommentId());
            return  commentFileUploadService.removeList(collect);
//            this.removeBatchByIds(list);
        }
        return commentMapper.removeOne(comment.getCommentId()) != 0;
    }

    @Override
    // 商家回复评论
    public String replyComment(replyCommentParam bean, String userId) throws Exception {
        Comment one = this.getOne(new LambdaQueryWrapper<Comment>().eq(Comment::getOrderId, bean.getOrderId()).eq(Comment::getCommentId, bean.getCommentId()));
        if (null == one) {
            throw new MealsException(EnumException.COMMENT_NULL_EXCEPTION);
        }
        one.setReplay(bean.getContent());
        boolean b = this.updateById(one);
        return b?"回复成功":"回复失败";
    }

    @Override
    // 查询评论
    public List<CommentDto> getComment(String userId) throws Exception {
        Result<UserInfoFeignDto> userInfo = userFeignClient.getUserInfo(userId);
        if (userInfo.getCode()!=200){
            throw new MealsException(EnumException.NET_ERROR_EXCEPTION);
        }
        List<CommentDto> commentDtos = new ArrayList<>();
        CommentDto commentDto = null;

        if (userInfo.getData().getRoleId().equals("2")){
            Store store = storeService.getOne(new LambdaQueryWrapper<Store>().eq(Store::getUserId,userId));
            System.out.println("storeId"+store.getStoreId());
            List<Comment> list = this.list(new LambdaQueryWrapper<Comment>().eq(Comment::getStoreId, store.getStoreId()));
            for (Comment comment : list) {
                if (comment.getPictureFlag()==1){
                    commentDtos.add(this.copyCommentDto(comment, commentDto));
                }else {
                    commentDto = BeanUtil.copyProperties(comment, CommentDto.class);
                    commentDtos.add(commentDto);
                }
            }
        }
        if (userInfo.getData().getRoleId().equals("1")){
            List<Comment> list = this.list(new LambdaQueryWrapper<Comment>().eq(Comment::getUserId, userInfo.getData().getUserId()));
            for (Comment comment : list) {
                if (comment.getPictureFlag()==1){
                    commentDtos.add(this.copyCommentDto(comment, commentDto));
                }else {
                    commentDto = BeanUtil.copyProperties(comment, CommentDto.class);
                    commentDtos.add(commentDto);
                }
            }
        }
        return commentDtos;
    }

    @Override
    public Integer calculateStoreScore(List<String> orderIds) throws Exception {
        if (!orderIds.isEmpty()){
          List<Comment> comments = commentMapper.calRate(orderIds);
          return comments.stream().mapToInt(Comment::getRate).sum()/orderIds.size();
        }
        return 0;
    }

    @Override
    public List<CommentDto> getCommentByStoreId(String storeId) {
        List<Comment> store_id = this.list(new QueryWrapper<Comment>().eq("store_id", storeId));
        List<CommentDto> commentDtos = BeanUtil.copyToList(store_id, CommentDto.class);
        return commentDtos;
    }

    @Override
    public PageInfo<CommentDto> getPageComment(String userId, Integer pageNum, Integer pageSize) throws Exception {
        Page<Comment> commentPage = new Page<>(pageNum == null ? 1 : pageNum, pageSize == null ? 5 : pageSize);
        CommentDto commentDto = null;
        List<CommentDto> commentDtos = new ArrayList<>();
        if (userId != null) {
            Store store = storeService.getOne(new LambdaQueryWrapper<Store>().eq(Store::getUserId,userId));
            this.page(commentPage, new LambdaQueryWrapper<Comment>().eq(Comment::getStoreId, store.getStoreId()));
            for (Comment comment : commentPage.getRecords()) {
                if (comment.getPictureFlag()==1){
                    commentDtos.add(this.copyCommentDto(comment, commentDto));
                }else {
                    commentDto = BeanUtil.copyProperties(comment, CommentDto.class);
                    commentDtos.add(commentDto);
                }
            }
            PageInfo<CommentDto> commentDtoPageInfo = new PageInfo<>(commentPage, CommentDto.class);
            commentDtoPageInfo.setList(commentDtos);
            return commentDtoPageInfo;
        }
        return null;
    }

    @Override
    public PageInfo<CommentDto> getReplyComment(String userId, Integer pageNum, Integer pageSize) throws Exception {
        Page<Comment> commentPage = new Page<>(pageNum == null ? 1 : pageNum, pageSize == null ? 5 : pageSize);
        CommentDto commentDto = null;
        List<CommentDto> commentDtos = new ArrayList<>();
        if (userId != null) {
            Store store = storeService.getOne(new LambdaQueryWrapper<Store>().eq(Store::getUserId,userId));
            this.page(commentPage, new LambdaQueryWrapper<Comment>().eq(Comment::getStoreId, store.getStoreId()).isNotNull(Comment::getContent).isNull(Comment::getReplay));
            for (Comment comment : commentPage.getRecords()) {
                if (comment.getPictureFlag()==1){
                    commentDtos.add(this.copyCommentDto(comment, commentDto));
                }else {
                    commentDto = BeanUtil.copyProperties(comment, CommentDto.class);
                    commentDtos.add(commentDto);
                }
            }
            PageInfo<CommentDto> commentDtoPageInfo = new PageInfo<>(commentPage, CommentDto.class);
            commentDtoPageInfo.setList(commentDtos);
            return commentDtoPageInfo;
        }
        return null;
    }

    public CommentDto copyCommentDto(Comment comment,CommentDto commentDto){
        commentDto = BeanUtil.copyProperties(comment, CommentDto.class);
        List<CommentFileUpload> commentFileUploads = commentFileUploadService.list(new LambdaQueryWrapper<CommentFileUpload>().eq(CommentFileUpload::getOrderId, comment.getOrderId()));
        List<String> collect = commentFileUploads.stream().map(CommentFileUpload::getFilePath).collect(Collectors.toList());
        commentDto.setFilePath(collect);
        return commentDto;
    }



}
